package com.lhs.config;

import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch.core.bulk.BulkOperation;
import co.elastic.clients.elasticsearch.core.bulk.BulkResponseItem;
import co.elastic.clients.elasticsearch.indices.CreateIndexResponse;
import com.feign.blog.BlogFeignClient;
import com.lhs.entity.blog.article_search;
import com.lhs.entity.blog.blog_post;

import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@Component
public class BlogIndexInitializer {

    @Autowired
    private ElasticsearchClient client;

    @Autowired
    private BlogFeignClient blogFeignClient;

    @PostConstruct
    public void init() throws IOException {
        String indexName = "article_index";

        // 检查索引是否存在
        boolean exists = client.indices().exists(b -> b.index(indexName)).value();
        if (!exists) {
            log.info("🧩 索引 [{}] 不存在，开始创建...", indexName);

            CreateIndexResponse createResponse = client.indices().create(c -> c
                    .index(indexName)
                    .mappings(m -> m
                            .properties("id", p -> p.long_(lp -> lp))
                            .properties("title", p -> p.text(tp -> tp.analyzer("ik_max_word").searchAnalyzer("ik_smart")))
                            .properties("content", p -> p.text(tp -> tp.analyzer("ik_max_word").searchAnalyzer("ik_smart")))
                            .properties("cover", p -> p.keyword(tp -> tp))
                            .properties("label", p -> p.keyword(tp -> tp))
                            .properties("authorId", p -> p.long_(lp -> lp))
                            .properties("authorName", p -> p.text(tp -> tp.analyzer("ik_max_word").searchAnalyzer("ik_smart")))
                            .properties("authorAvatar", p -> p.keyword(tp -> tp))
                            .properties("status", p -> p.long_(lp -> lp))
                            .properties("likeCount", p -> p.long_(lp -> lp))
                            .properties("commentCount", p -> p.long_(lp -> lp))
                            .properties("viewCount", p -> p.long_(lp -> lp))
                            .properties("publishTime", p -> p.date(tp -> tp))
                            .properties("updateTime", p -> p.date(tp -> tp))
                    )
            );

            if (createResponse.acknowledged()) {
                log.info("✅ 成功创建索引 [{}]", indexName);
            }
        } else {
            log.info("✅ 索引 [{}] 已存在", indexName);
        }

        // 通过 Feign 获取博客数据
        List<article_search> allPosts = blogFeignClient.getAllBlogs();
        if (allPosts == null || allPosts.isEmpty()) {
            log.info("📭 从博客服务未获取到数据，无需导入。");
            return;
        }

        log.info("🚀 准备批量导入 {} 条博客数据到 Elasticsearch ...", allPosts.size());

        //  分批导入（每批 500 条）
        int batchSize = 5;
        List<BulkOperation> operations = new ArrayList<>();

        for (int i = 0; i < allPosts.size(); i++) {
            article_search post = allPosts.get(i);

            article_search doc = new article_search();
            doc.setId(post.getId());
            doc.setTitle(post.getTitle());
            doc.setContent(post.getContent());
            doc.setLikeCount(post.getLikeCount());
            doc.setViewCount(post.getViewCount());
            doc.setCommentCount(post.getCommentCount());
            doc.setStatus(post.getStatus());
            doc.setUpdateTime(post.getUpdateTime());
            doc.setCover(post.getCover());
            doc.setAuthorId(post.getAuthorId());
            doc.setAuthorName(post.getAuthorName());
            doc.setAuthorAvatar(post.getAuthorAvatar());
            doc.setLabel(post.getLabel());
            doc.setCreateTime(post.getCreateTime());
            doc.setPublishTime(post.getPublishTime());

            operations.add(BulkOperation.of(b -> b
                    .index(idx -> idx
                            .index(indexName)
                            .id(String.valueOf(doc.getId()))
                            .document(doc)
                    )
            ));

            // 达到批量阈值或最后一批时提交
            if (operations.size() >= batchSize || i == allPosts.size() - 1) {
                var bulkResponse = client.bulk(b -> b.operations(operations));
                if (bulkResponse.errors()) {
                    for (BulkResponseItem item : bulkResponse.items()) {
                        if (item.error() != null) {
                            log.error("❌ 导入失败：{}", item.error().reason());
                        }
                    }
                } else {
                    log.info("✅ 成功导入 {} 条文档", operations.size());
                }
                operations.clear(); // 清空本批操作
            }
        }

        log.info("🎉 全部导入完成，共 {} 条数据。", allPosts.size());
    }
}
